package com.liu.backstage.Aop;

import com.liu.backstage.model.Syslog;
import com.liu.backstage.model.Users;
import com.liu.backstage.service.SyslogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @Author ：腾杰
 * @Date ：2020年07月11日 0011 16:31
 * @Description ：
 */
@Component
@Aspect
public class LogAop {
    @Autowired
    private HttpServletRequest request;

    @Autowired
    private SyslogService syslogService;

    private Date visitTime;  // 系统访问开始时间
    private Class clazz;     // 访问的类
    private Method method;   // 访问的方法
    private  String methodName;

    //前置通知  主要是获取开始时间、执行的类是哪一个、执行的是哪一个方法
    @Before("execution(* com.liu.backstage.controller.*.*(..))")
    public void doBefore(JoinPoint joinPoint) throws NoSuchMethodException {
        visitTime=new Date();
        clazz=joinPoint.getTarget().getClass(); // 具体要让问的类
        methodName=joinPoint.getSignature().getName(); // 获取访问的方法名称
        Object[] args=joinPoint.getArgs();


        if (args==null||args.length==0){
            // 获取无参数的方法
            method=clazz.getMethod(methodName);
        }else{
            Class[] classes = new Class[args.length];
            for (int i=0;i<args.length;i++){
                classes[i]=args[i].getClass();
            } //获取参数
            method=clazz.getMethod(methodName,classes);
        }
    }
    // 后置通知
    @After("execution(* com.liu.backstage.controller.*.*(..))")
    public void doAfter(JoinPoint joinPoint) throws Exception {
        long time = new Date().getTime() - visitTime.getTime();
        // 获取 url
        String url = "";
        if (clazz != null && methodName != null && clazz != Syslog.class) {
            url =joinPoint.getSignature().getDeclaringTypeName();//接口全路径
            // 获取访问的IP
            String ip = request.getRemoteAddr();
            // 获取当前操作的用户
            String username=SecurityContextHolder.getContext().getAuthentication().getName();// 从上下文中获取当前登录的用户对象
//            SecurityContext context = SecurityContextHolder.getContext();
//            Users user =(Users)context.getAuthentication().getPrincipal();
//            String userName = user.getUsername();
            // 将日志相关信息封装在SysLog 对象
            Syslog sysLog = new Syslog();
            sysLog.setExecutionTime(time);
            sysLog.setIp(ip);
            sysLog.setMethod("[类名] " + clazz.getName() + " [方法名] " + methodName);
            sysLog.setUrl(url);
            sysLog.setUsername(username);
            sysLog.setVisitTime(visitTime);
            // 调用Service完成操作
            if (clazz.getName()!= "com.liu.backstage.Aop.LogAop") {
                syslogService.save(sysLog);
            }
        }
    }
}
